﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using Windows.UI.Core;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Markup;

namespace DT.GoogleAnalytics.Metro
{
    internal class HostControl : Control
    {
        /// <summary>
        /// newline is required in the beginning
        /// </summary>
        private const string MainJsCode = @"
var _gaq = _gaq || [];
window.external.notify('trying to get tracker');
window.PageTracker = _gat._createTracker(window.GoogleAnalyticsId);
window.PageTracker._setDomainName('none');
window.external.notify('GoogleAnalytics.Initialized');
";

        private const string AccountDetailsJs = "window.GoogleAnalyticsId = '{0}'";

        internal event Action<HostControl> Initialized;

        public HostControl()
        {
            DefaultStyleKey = typeof(HostControl);
        }

        public HostControl(string trackingId)
            : this()
        {
            TrackingId = trackingId;
            //limitation of WinRT API http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/b827ce9d-09c9-4eaf-8cbf-198b44add90f
            var controlTemplate = XamlReader.LoadWithInitialTemplateValidation("<ControlTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' " +
                                                  " " +
                                                  ">" +
                "<Canvas x:Name=\"PART_Root\"/>" +
                                                  "</ControlTemplate>") as ControlTemplate;

            this.Template = controlTemplate;
            //XamlReader.LoadWithInitialTemplateValidation()
        }

        public string TrackingId { get; set; }
        private Canvas PART_Root = null;
        private WebView _webView = null;

        protected override void OnApplyTemplate()
        {
            PART_Root = (Canvas)GetTemplateChild("PART_Root");
            if (PART_Root == null)
            {
                return;
            }
            InitializeWebView();
        }

        private void InitializeWebView()
        {
            if (_webView == null)
            {
                _webView = new WebView();
                if (PART_Root != null)
                {
                    PART_Root.Children.Add(_webView);
                    _webView.LoadCompleted += WebViewLoadCompleted;
                    _webView.ScriptNotify += WebViewScriptNotify;
                    _webView.NavigationFailed += _webView_NavigationFailed;
                    _webView.Navigate(new Uri("ms-appx-web:///blank.html", UriKind.RelativeOrAbsolute));
                }
            }
        }

        private void _webView_NavigationFailed(object sender, WebViewNavigationFailedEventArgs e)
        {

        }

        private void WebViewScriptNotify(object sender, NotifyEventArgs e)
        {
            var stringResult = e.Value;
            if (stringResult == "GoogleAnalytics.Initialized")
            {
                OnGoogleAnalyticsInitialized();
            }
        }

        private void WebViewLoadCompleted(object sender, Windows.UI.Xaml.Navigation.NavigationEventArgs e)
        {
            var js = string.Format(AccountDetailsJs, TrackingId) + MainJsCode;
            try
            {
                _webView.InvokeScriptAsync("eval", new string[] { js });
            }
            catch (Exception exception)
            {
                Debug.WriteLine("[w8ga] initialization failed: {0}", exception);
            }
        }

        private void OnGoogleAnalyticsInitialized()
        {
            if (Initialized != null)
            {
                Initialized(this);
            }
        }

        internal void RunAnalyticsJsCode(string fullJsCode)
        {
            Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                try
                {
                    _webView.InvokeScriptAsync("eval", new[] { fullJsCode });
                }
                catch (Exception exception)
                {
                    Debug.WriteLine("[w8ga] analytic event failed: {0}", exception);
                }
            });
        }
    }
}
